package cn.tedu._05weibo.controller;

import cn.tedu._05weibo.common.response.JsonResult;
import cn.tedu._05weibo.common.response.StatusCode;
import cn.tedu._05weibo.mapper.UserMapper;
import cn.tedu._05weibo.pojo.dto.UserLoginDTO;
import cn.tedu._05weibo.pojo.dto.UserRegDTO;
import cn.tedu._05weibo.pojo.entity.User;
import cn.tedu._05weibo.pojo.vo.UserVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpSession;
import java.util.Date;

/**
 * Slf4j注解:
 *   1.日志注解, 用于打印日志;
 *   2.添加此注解后,为该类创建一个日志对象log,使用该日志对象即可打印不同级别的日志
 *     log.trace("追踪信息");
 *     log.debug("调试信息")[打印调试信息,一般用于开发测试阶段];
 *     log.info("运行信息");
 *     log.warn("警告信息");
 *     log.error("错误信息")[打印错误信息,一般在全局异常处理器中使用];
 */

/**
 * Knife4j相关注解:
 *   1.Api(tags="")注解: 调整控制器类名在Knife4j文档中的显示名称;
 *   2.ApiOperation(value="")注解: 调整控制器方法名在Knife4j文档中的显示名称;
 *   3.ApiIgnore注解: 忽略此注解修饰的参数,不显示在Knife4j文档中;
 *   4.ApiModelProperty(value="",required=true,example="")POJO类属性描述;
 *   5.ApiImplicitParam(name="",value="",required=true,dataType="")声明参数方式接收时对参数描述;
 *   6.ApiImplicitParams(value={})多个参数进行描述;
 */

@Api(tags = "01.用户模块")
@Slf4j
@RestController
@RequestMapping("/v1/users/")
public class UserController {
    //自动装配
    @Autowired
    private UserMapper userMapper;

    /**
     * 1.注册功能
     */
    @ApiOperation(value = "注册功能")
    @PostMapping("reg")
    public JsonResult reg(@RequestBody @Validated UserRegDTO userRegDTO){
        //打印调试信息
        log.debug("userRegDTO = " + userRegDTO);
        /*
            1.接收客户端传递的数据;
            2.数据合法性校验[此处暂不校验];
            3.确认用户名是否被占用[SELECT接口];
              3.1 被占用: return 2;
              3.2 未被占用: 插入数据[INSERT接口], return 1;
         */
        //是否被占用
        String username = userRegDTO.getUsername();
        UserVO userVO = userMapper.selectByUsername(username);
        //打印调试信息
        log.debug("userVO = " + userVO);
        if (userVO != null){//被占用
            return new JsonResult(StatusCode.USERNAME_EXISTS);
        }
        //未被占用
        User user = new User();
        BeanUtils.copyProperties(userRegDTO, user);
        user.setCreated(new Date());
        //打印调试信息
        log.debug("user = " + user);
        userMapper.insertUser(user);

        return JsonResult.ok();
    }

    /**
     * 2.登录功能
     *   1.接收客户端传递的数据;
     *   2.确认用户名是否正确[SELECT接口];
     *     2.1 错误: return 3;
     *     2.2 正确: 确认密码是否正确;
     *         2.2.1 密码错误: return 2;
     *         2.2.2 密码正确: return 1;
     */
    @ApiOperation(value = "登录功能")
    @PostMapping("login")
    public JsonResult login(@RequestBody UserLoginDTO userLoginDTO, @ApiIgnore HttpSession session){
        //soutp + 回车
        log.debug("userLoginDTO = " + userLoginDTO);
        //确认用户名是否正确
        String username = userLoginDTO.getUsername();
        UserVO userVO = userMapper.selectByUsername(username);
        if (userVO == null){//用户名错误
            return new JsonResult(StatusCode.USERNAME_ERROR);
        }
        //比较密码
        if (userVO.getPassword().equals(userLoginDTO.getPassword())){
            //会话:存储唯一标识
            session.setAttribute("user", userVO);
            return JsonResult.ok();//登录成功
        }

        return new JsonResult(StatusCode.PASSWORD_ERROR); //密码错误
    }

    /**
     * 3.获取当前用户功能
     */
    @ApiOperation(value = "获取当前用户功能")
    @GetMapping("currentUser")
    public JsonResult currentUser(@ApiIgnore HttpSession session){
        //获取会话中的用户信息
        UserVO userVO = (UserVO) session.getAttribute("user");

        return JsonResult.ok(userVO);
    }

    /**
     * 4.退出登录功能
     *   4.1 登录成功;
     *   4.2 获取当前用户信息;
     *   4.3 退出登录;
     *   4.3 获取当前用户信息;
     */
    @ApiOperation(value = "退出登录功能")
    @GetMapping("logout")
    public void logout(@ApiIgnore HttpSession session){
        //删除会话信息
        session.removeAttribute("user");
    }
}









